package com.ruoyi.system.service.impl;

import java.io.File;
import java.io.IOException;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.WordTemplateUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.enums.BusType;
import com.ruoyi.system.mapper.*;
import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.ITicketBusinessService;
import com.ruoyi.system.service.TicketCommonService;
import com.ruoyi.system.utils.GenerateCodeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.system.service.ITicketTransService;

import javax.validation.Validator;
import javax.validation.constraints.Size;

/**
 * 交易信息Service业务层处理
 *
 * @author ruoyi
 * @date 2024-07-15
 */
@Service
public class TicketTransServiceImpl implements ITicketTransService
{
    private static final Logger log = LoggerFactory.getLogger(TicketTransServiceImpl.class);

    @Autowired
    private TicketTransMapper ticketTransMapper;

    @Autowired
    private TicketReceiptMapper receiptMapper;

    @Autowired
    private TicketTemplateMapper templateMapper;

    @Autowired
    private TicketSealMapper sealMapper;

    @Autowired
    private TicketReceiptRealMapper receiptRealMapper;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private TicketCommonService commonService;

    @Autowired
    private ITicketBusinessService businessService;

    @Autowired
    protected Validator validator;

    /**
     * 查询交易信息
     *
     * @param transNo 交易信息主键
     * @return 交易信息
     */
    @Override
    public TicketTrans selectTicketTransByTransNo(String transNo)
    {
        return ticketTransMapper.selectTicketTransByTransNo(transNo);
    }

    /**
     * 查询交易信息列表
     *
     * @param ticketTrans 交易信息
     * @return 交易信息
     */
    @Override
    public List<TicketTrans> selectTicketTransList(TicketTrans ticketTrans)
    {
        List<TicketTrans> trans = ticketTransMapper.selectTicketTransList(ticketTrans);

        //判断当前登录人是否是商户
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long userId = loginUser.getUserId();
        SysUser sysUser = userService.selectUserById(userId);
        @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符") String nickName = sysUser.getNickName();
        if(commonService.isBusiness()){
            TicketBusiness business = businessService.selectTicketBusinessByBusinessName(nickName);
            String businessPhone = business.getBusinessPhone();
            trans= trans
                    .stream()
                    .filter(p->p.getCreateBy().equals(businessPhone))
                    .collect(Collectors.toList());
            //判断是否是用户
        }
        return trans;
    }

    /**
     * 新增交易信息
     *
     * @param ticketTrans 交易信息
     * @return 结果
     */
    @Override
    public int insertTicketTrans(TicketTrans ticketTrans)
    {
        if(StringUtils.isEmpty(ticketTrans.getTransNo())){
            ticketTrans.setTransNo(UUID.randomUUID().toString());
        }
        LoginUser loginUser = SecurityUtils.getLoginUser();
        ticketTrans.setCreateBy(loginUser.getUsername());
        ticketTrans.setCreateTime(DateUtils.getNowDate());
        return ticketTransMapper.insertTicketTrans(ticketTrans);
    }

    @Override
    public String importTrans(List<TicketTrans> transList, Boolean isUpdateSupport, String operName) {
        if (StringUtils.isNull(transList) || transList.size() == 0)
        {
            throw new ServiceException("导入交易数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (TicketTrans trans : transList)
        {
            try
            {
                BeanValidators.validateWithException(validator, trans);
                trans.setCreateBy(operName);
                this.insertTicketTrans(trans);
                successNum++;
                successMsg.append("<br/>" + successNum + "、交易 " + trans.getTransName() + " 导入成功");
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、交易 " + trans.getTransName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    /**
     * 修改交易信息
     *
     * @param ticketTrans 交易信息
     * @return 结果
     */
    @Override
    public int updateTicketTrans(TicketTrans ticketTrans)
    {
        ticketTrans.setUpdateTime(DateUtils.getNowDate());
        return ticketTransMapper.updateTicketTrans(ticketTrans);
    }

    /**
     * 批量删除交易信息
     *
     * @param transNos 需要删除的交易信息主键
     * @return 结果
     */
    @Override
    public int deleteTicketTransByTransNos(String[] transNos)
    {
        return ticketTransMapper.deleteTicketTransByTransNos(transNos);
    }

    @Override
    public int generateReceipts(String[] transNos, String templateNo, String sealNo) {
        //根据交易编号批量生成收据信息
        for (String transNo : transNos) {
            dealTransToReceipt(transNo,templateNo,sealNo);
        }
        for (String transNo : transNos){
            String receiptUrl = generateReceipt(transNo, templateNo, sealNo);
            TicketTrans ticketTrans = ticketTransMapper.selectTicketTransByTransNo(transNo);
            int dirLastIndex = RuoYiConfig.getProfile().length() + 1;
            String currentDir = StringUtils.substring(RuoYiConfig.getUploadPath(), dirLastIndex);
            receiptUrl = Constants.RESOURCE_PREFIX + "/" + currentDir + "/" + receiptUrl;
            ticketTrans.setImgContent(receiptUrl);
            ticketTransMapper.updateTicketTrans(ticketTrans);
        }
        return 1;
    }

    public String generateReceipt(String transNo, String templateNo, String sealNo){
        TicketTrans ticketTrans = ticketTransMapper.selectTicketTransByTransNo(transNo);
        TicketTemplate ticketTemplate = templateMapper.selectTicketTemplateByTemplateNo(templateNo);
        String templatePath = null;
        if(!Objects.isNull(ticketTemplate)){
            templatePath=ticketTemplate.getTemplateInfo();
            String upload = templatePath.split("upload")[1];
            templatePath=RuoYiConfig.getUploadPath()+upload;
            System.out.println(templatePath);
        }
        String randomString = GenerateCodeUtil.generateRandomString();
        String pdfPath = RuoYiConfig.getUploadPath()+ File.separator+randomString+".pdf";
        String filePath = RuoYiConfig.getUploadPath()+File.separator+randomString+".docx";
        Map<String, Object> map = new HashMap<>();
        map.put("TransDate",ticketTrans.getTransDate());
        map.put("TransAddr",ticketTrans.getTransAddr());
        map.put("TransAmount",ticketTrans.getTransAmount());
        map.put("TransName",ticketTrans.getTransName());
        String transBusinessNo = ticketTrans.getTransBusinessNo();

        map.put("BusinessName", transBusinessNo);
        map.put("CustomerName",ticketTrans.getTransCustomerNo());
        TicketSeal ticketSeal = sealMapper.selectTicketSealBySealNo(sealNo);
        String sealContent = ticketSeal.getSealContent();
        String upload = sealContent.split("upload")[1];
        sealContent=RuoYiConfig.getUploadPath()+upload;
        System.out.println(sealContent);
        map.put("SealURL",sealContent);
        // 方法调用
        WordTemplateUtils.compileWordTemplate(templatePath,filePath,map);
        try {
            WordTemplateUtils.wordToPdf(filePath,pdfPath);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String fileToImages = WordTemplateUtils.pdfFileToImages(pdfPath, RuoYiConfig.getUploadPath());
        return fileToImages;
    }

    /**
     * 根据交易编号生成收据
     * @param transNo 交易编号
     * @param templateNo 模板编号
     * @param sealNo 印章编号
     */
    public void dealTransToReceipt(String transNo, String templateNo, String sealNo){
        TicketTemplate ticketTemplate=new TicketTemplate();
        TicketSeal ticketSeal= new TicketSeal();
        if(StringUtils.isEmpty(templateNo)){
            //使用默认模板
        }else {
            //模板信息
            ticketTemplate = templateMapper.selectTicketTemplateByTemplateNo(templateNo);
        }
        //印章信息
        if(StringUtils.isEmpty(sealNo)){
            //使用默认印章
        }else {
            ticketSeal=sealMapper.selectTicketSealBySealNo(sealNo);
        }
        TicketTrans ticketTrans = ticketTransMapper.selectTicketTransByTransNo(transNo);
        //商户编号
        String transBusinessNo = ticketTrans.getTransBusinessNo();
        //客户编号
        String transCustomerNo = ticketTrans.getTransCustomerNo();
        //收据名称规则：商户名称@客户名称收据单@本联与副联
        TicketReceipt ticketBusinessReceipt = new TicketReceipt();
        String busTicketNo = UUID.randomUUID().toString();
        ticketBusinessReceipt.setReceiptNo(busTicketNo);
        ticketBusinessReceipt.setReceiptName(transBusinessNo+"@"+transCustomerNo+"收据单@"+BusType.merchant.name());
        ticketBusinessReceipt.setReceiptTransNo(transNo);
        ticketBusinessReceipt.setReceiptTransName(ticketTrans.getTransName());
        ticketBusinessReceipt.setReceiptBusType(BusType.merchant.name());
        ticketBusinessReceipt.setReceiptTemplateNo(ticketTemplate.getTemplateNo());
        ticketBusinessReceipt.setReceiptTemplateName(ticketTemplate.getTemplateName());
        ticketBusinessReceipt.setReceiptSealNo(ticketSeal.getSealNo());
        ticketBusinessReceipt.setReceiptSealName(ticketSeal.getSealName());
        //本联随机校验码
        String randomBusCode = GenerateCodeUtil.generateRandomCode(8);
        ticketBusinessReceipt.setRemark(randomBusCode);
        TicketReceipt ticketCustomerReceipt = new TicketReceipt();
        String personTicketNo = UUID.randomUUID().toString();
        ticketCustomerReceipt.setReceiptNo(personTicketNo);
        ticketCustomerReceipt.setReceiptName(transBusinessNo+"@"+transCustomerNo+"收据单@"+BusType.person.name());
        ticketCustomerReceipt.setReceiptTransNo(transNo);
        ticketCustomerReceipt.setReceiptTransName(ticketTrans.getTransName());
        ticketCustomerReceipt.setReceiptBusType(BusType.person.name());
        ticketCustomerReceipt.setReceiptTemplateNo(ticketTemplate.getTemplateNo());
        ticketCustomerReceipt.setReceiptTemplateName(ticketTemplate.getTemplateName());
        ticketCustomerReceipt.setReceiptSealNo(ticketSeal.getSealNo());
        ticketCustomerReceipt.setReceiptSealName(ticketSeal.getSealName());
        String randomPersonCode = GenerateCodeUtil.generateRandomCode(8);
        ticketCustomerReceipt.setRemark(randomPersonCode);
        receiptMapper.insertTicketReceipt(ticketBusinessReceipt);
        receiptMapper.insertTicketReceipt(ticketCustomerReceipt);
        //生成票据后插入本副联关系便于查票及防伪
        TicketReceiptReal ticketReceiptReal = new TicketReceiptReal();
        ticketReceiptReal.setReceiptRealNo(UUID.randomUUID().toString());
        ticketReceiptReal.setBusTicketNo(busTicketNo);
        ticketReceiptReal.setPersonTicketNo(personTicketNo);
        ticketReceiptReal.setBusTicketCode(randomBusCode);
        ticketReceiptReal.setPersonTicketCode(randomPersonCode);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        ticketReceiptReal.setCreateBy(loginUser.getUsername());
        ticketReceiptReal.setCreateTime(DateUtils.getNowDate());
        receiptRealMapper.insertTicketReceiptReal(ticketReceiptReal);
    }

    /**
     * 删除交易信息信息
     *
     * @param transNo 交易信息主键
     * @return 结果
     */
    @Override
    public int deleteTicketTransByTransNo(String transNo)
    {
        return ticketTransMapper.deleteTicketTransByTransNo(transNo);
    }
}
